- Bioconductor (Durinck et al.
(2009))
- R language (R Core Team (2022))
- Article (Adams et al. (2019))
- Rmarkdown (Allaire et al. (2021))
- edgeR (Robinson, DJ, and Smyth
(2010))
- GEOquery (Davis and Meltzer
(2007))
- SHH (Magliano et al. (2006))
- Limma (Ritchie et al. (2015))
- ComplexHeatMap (Gu (2022))
- Circlize (Gu et al. (2014))
Installing Dependencies
if (!requireNamespace("BiocManager", quietly = TRUE)){
install.packages("BiocManager")}
if (!requireNamespace("edgeR", quietly = TRUE)){
BiocManager::install("edgeR")}
if (!requireNamespace("GEOquery", quietly = TRUE)){
BiocManager::install("GEOquery")}
if (!requireNamespace("ComplexHeatmap", quietly = TRUE)){
BiocManager::install("ComplexHeatmap")}
if (!requireNamespace("limma", quietly = TRUE)){
BiocManager::install("limma")}
if (!requireNamespace("ExpressionSet", quietly = TRUE)){
BiocManager::install("ExpressionSet")}
Warning: package ‘ExpressionSet’ is not available for Bioconductor version '3.16'
A version of this package for your version of R might be available elsewhere,
see the ideas at
https://cran.r-project.org/doc/manuals/r-patched/R-admin.html#Installing-packagesWarning: downloaded length 0 != reported length 6873Warning: cannot open URL 'https://bioconductor.org/packages/3.16/data/annotation/bin/macosx/big-sur-arm64/contrib/4.2/PACKAGES.rds': HTTP status was '404 Not Found'Warning: downloaded length 0 != reported length 6873Warning: cannot open URL 'https://bioconductor.org/packages/3.16/data/annotation/bin/macosx/big-sur-arm64/contrib/4.2/PACKAGES.gz': HTTP status was '404 Not Found'Warning: downloaded length 0 != reported length 6873Warning: cannot open URL 'https://bioconductor.org/packages/3.16/data/experiment/bin/macosx/big-sur-arm64/contrib/4.2/PACKAGES.rds': HTTP status was '404 Not Found'Warning: downloaded length 0 != reported length 6873Warning: cannot open URL 'https://bioconductor.org/packages/3.16/data/experiment/bin/macosx/big-sur-arm64/contrib/4.2/PACKAGES.gz': HTTP status was '404 Not Found'Warning: downloaded length 0 != reported length 6873Warning: cannot open URL 'https://bioconductor.org/packages/3.16/workflows/bin/macosx/big-sur-arm64/contrib/4.2/PACKAGES.rds': HTTP status was '404 Not Found'Warning: downloaded length 0 != reported length 6873Warning: cannot open URL 'https://bioconductor.org/packages/3.16/workflows/bin/macosx/big-sur-arm64/contrib/4.2/PACKAGES.gz': HTTP status was '404 Not Found'Warning: downloaded length 0 != reported length 6873Warning: cannot open URL 'https://bioconductor.org/packages/3.16/books/bin/macosx/big-sur-arm64/contrib/4.2/PACKAGES.rds': HTTP status was '404 Not Found'Warning: downloaded length 0 != reported length 6873Warning: cannot open URL 'https://bioconductor.org/packages/3.16/books/bin/macosx/big-sur-arm64/contrib/4.2/PACKAGES.gz': HTTP status was '404 Not Found'
Update all/some/none? [a/s/n]:
n
if (!requireNamespace("circlize", quietly = TRUE)){
BiocManager::install("circlize")}
if (!requireNamespace("gprofiler2", quietly = TRUE))
BiocManager::install("gprofiler2")
if (!requireNamespace("kableExtra", quietly = TRUE))
BiocManager::install("kableExtra")
if (!requireNamespace("plotly", quietly = TRUE))
BiocManager::install("plotly")
if (!requireNamespace("dplyr", quietly = TRUE))
BiocManager::install("dplyr")
library(dplyr)
library(plotly)
Part 1: Loading the normalized gene data
The normalized data has already been written into a text file by the
previous Assignment 1. For better assessment, I have indicated it on the
file uploaded.
normalized_count_data <- read.table(file=file.path(getwd(), "normalized_counts_annotated")
, header = TRUE, stringsAsFactors = FALSE, check.names = FALSE )
knitr::kable(normalized_count_data[1:10,1:7], type="pipe")
|
hgnc_symbol
|
YRE1A
|
YRE1B
|
YRE2A
|
YRG1A
|
YRG1B
|
YRG2B
|
|
A4GALT
|
4.345648
|
3.111477
|
2.408097
|
5.369569
|
6.397003
|
6.796014
|
|
AAAS
|
19.317681
|
22.327817
|
21.792253
|
18.384756
|
17.419577
|
17.311220
|
|
AACS
|
32.913059
|
24.534108
|
24.466495
|
23.731644
|
17.621289
|
17.428989
|
|
AADACP1
|
2.418554
|
4.507231
|
3.916687
|
13.734990
|
14.270060
|
14.143042
|
|
AADAT
|
4.058510
|
3.995899
|
3.647402
|
4.637361
|
4.052613
|
3.678086
|
|
AAED1
|
14.351471
|
11.913866
|
12.242066
|
12.711562
|
8.425186
|
7.790737
|
|
AAGAB
|
36.922469
|
35.816951
|
39.338927
|
40.358329
|
31.836730
|
30.961949
|
|
AAK1
|
1.531217
|
1.364910
|
1.534162
|
2.165459
|
2.677295
|
2.667404
|
|
AAMDC
|
46.807715
|
44.246410
|
48.924065
|
66.090858
|
49.702345
|
44.178113
|
|
AAMP
|
82.175802
|
88.352333
|
93.832788
|
76.203567
|
81.078221
|
82.443384
|
Part 2: Defining Portions of the Heatmap Matrix
I am defining the elements of the normalized data matrix which I will
be using for the heatmap later.
Part 3: Creating Heatmap
The heatmap uses different colors for the expression data. The
heatmap has many genes clustered based on their expression at different
levels such as control (EA1,EA2,EB1) or the cells treated with GLI2
(G1A,G2A,G1B).
if(min(heatmap_matrix) == 0){
heatmap_col = circlize::colorRamp2(c( 0, max(heatmap_matrix)),
c("white", "purple"))
} else {
heatmap_col = circlize::colorRamp2(c(min(heatmap_matrix), 0,
max(heatmap_matrix)), c("darkgreen", "white", "purple"))
}
first_heatmap <- ComplexHeatmap::Heatmap(as.matrix(heatmap_matrix),
show_row_dend = TRUE, show_column_dend = TRUE,
col=heatmap_col, show_column_names = TRUE,
show_row_names = FALSE, show_heatmap_legend = TRUE)
first_heatmap

Part 4: SPP1 EMT Genes-Conclusion justification
SPP1 is an EMT genes It shows higher expression when treated with
GLI2 compare to empty vector control cells (EV). This has been also
proved by the authors. However, indicating this again would strengthen
the hypothesis corresponding to Dox treated cells having GLI2 vector
show higher EMT gene expression as opposed to controls having empty
vector showing less expression of the genes.
GLI2_treatment_samples <- grep(colnames(normalized_count_data),pattern = "\\G")
EV_tratment_samples <- grep(colnames(normalized_count_data),pattern = "\\E")
gene_of_interest <- which(normalized_count_data$Gene_symbol == "SPP1")
YAPC_GLI2_samples <- t(normalized_count_data[gene_of_interest,5:7])
colnames(YAPC_GLI2_samples) <- c("GLI2_vector_cells")
YAPC_EV_samples <- t(normalized_count_data[gene_of_interest,2:4])
colnames(YAPC_EV_samples) <- c("Empty_Vector_cells")
YAPC_GLI2_samples
GLI2_vector_cells
YRG1A 321.9614
YRG1B 607.5096
YRG2B 580.2982
YAPC_EV_samples
Empty_Vector_cells
YRE1A 1.307170
YRE1B 1.616595
YRE2A 1.752119
Part 5: T-test between EV and GLI2
GLI2 treated cells are different in terms of their expression from
the empty vector cells. P value (0.03135) < 0.05. Indeed this shows
there is significant difference. However, this requires to see if GLI2
treatments show difference among one another so the control cells.
t.test(x=t(YAPC_GLI2_samples), y=t(YAPC_EV_samples))
Welch Two Sample t-test
data: t(YAPC_GLI2_samples) and t(YAPC_EV_samples)
t = 5.5139, df = 2, p-value = 0.03135
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
110.2125 893.1831
sample estimates:
mean of x mean of y
503.256412 1.558628
PART 6: MDS Plot for Sample Clustering
The MDS plot allowed to visualize the difference within the different
cell types Earlier examples of MDS plot showed similar results. I
hypothesize that GLI2 expression is higher than control cell’s
expression levels due to DOX induction of EMT genes. In general I have
observed Gli2 cells to be less clustered, due to higher differential
expression among GLI2 cells.
limma::plotMDS(heatmap_matrix,col=c(rep("darkgreen",3), rep("blue",3)))

Part 7: Model Building of GLI2 expression status
The model I am building is based upon GLI2 expression status of genes
that are showing higher expression with significant indications of the
differential expression.
samples <- data.frame(lapply(colnames(normalized_count_data)[2:7],
FUN=function(x){unlist(strsplit(x, split = "[0-9]"))[c(1)]}))
colnames(samples) <- colnames(colnames(normalized_count_data)[2:7])
rownames(samples) <- c("Treatments")
samples <- data.frame(t(samples))
knitr::kable(samples, type = "pipe")
|
Treatments
|
|
YRE
|
|
YRE
|
|
YRE
|
|
YRG
|
|
YRG
|
|
YRG
|
YRG_model <- model.matrix( ~ samples$Treatments)
knitr::kable(YRG_model[1:6,], type = "pipe")
|
(Intercept)
|
samples$TreatmentsYRG
|
|
1
|
0
|
|
1
|
0
|
|
1
|
0
|
|
1
|
1
|
|
1
|
1
|
|
1
|
1
|
Part 8: Model Fitting and Differential Expression Calculation
The differential expression data matrix corresponding to gene symbols
were merged with the matrix that has the fitted model. The
Benjamin-hochberg correction method was applied to adjust the expression
data.
expressionMatrix <- as.matrix(normalized_count_data[,2:7])
rownames(expressionMatrix) <- normalized_count_data$Gene_symbol
colnames(expressionMatrix) <- colnames(normalized_count_data)[2:7]
set_expression_matrix <- Biobase::ExpressionSet(assayData = expressionMatrix)
fit <- limma::lmFit(set_expression_matrix, YRG_model)
fit_Bayes <- limma::eBayes(fit, trend = TRUE)
BH_method_fit <- limma::topTable(fit_Bayes,
coef = ncol(YRG_model),
adjust.method = "BH",
number = nrow(expressionMatrix))
merged_hits <- merge(normalized_count_data$Gene_symbol,
BH_method_fit,
by.y=0,by.x=1,
all.y=TRUE)
merged_hits <- merged_hits[order(merged_hits$P.Value),]
colnames(merged_hits) <- c("Gene_symbol","logFC", "AveExpr", "t",
"P.Value","adj.P.Val", "B")
rownames(merged_hits) <- 1:nrow(merged_hits)
knitr::kable(merged_hits[1:10,1:7], type = "pipe", row.names = FALSE,)
|
Gene_symbol
|
logFC
|
AveExpr
|
t
|
P.Value
|
adj.P.Val
|
B
|
|
S100A2
|
192.67873
|
105.164286
|
63.79569
|
0e+00
|
0.0000245
|
1.820600
|
|
SSFA2
|
76.45805
|
75.591839
|
45.17567
|
0e+00
|
0.0000789
|
1.781362
|
|
NT5E
|
86.27685
|
123.407858
|
42.93449
|
0e+00
|
0.0000789
|
1.773004
|
|
S100A13
|
132.80964
|
179.285328
|
37.98876
|
0e+00
|
0.0001191
|
1.749192
|
|
TRIB2
|
51.68968
|
38.062060
|
35.69100
|
1e-07
|
0.0001361
|
1.734718
|
|
HEG1
|
-13.44713
|
8.317468
|
-31.24508
|
1e-07
|
0.0002423
|
1.697467
|
|
NTN4
|
35.83705
|
33.048568
|
28.42566
|
2e-07
|
0.0003561
|
1.664696
|
|
UCP2
|
80.78518
|
94.331418
|
26.66241
|
3e-07
|
0.0004488
|
1.638993
|
|
PLLP
|
-31.42241
|
35.188668
|
-25.42904
|
4e-07
|
0.0004683
|
1.617932
|
|
UNC5B
|
19.59576
|
12.041479
|
24.78963
|
5e-07
|
0.0004683
|
1.605831
|
Part 9: P-value Assessment
The p-value was adjusted to have more stringent results. Normally
significant p-value is set to 0.05. However, I wanted to be more
stringent on my results and indicate the specific EMT genes. Probable
genes are 741. However, there are 27 genes that have significant
potential to be an EMT gene.
length(which(merged_hits$P.Value < 0.0005))
[1] 741
length(which(merged_hits$adj.P.Val < 0.0005))
[1] 27
Part 10: Model Visualization
This part of this assignment aims to detect SPP1’s role on how GLI2
cells are more differently expressed and do have higher difference than
the control cells. It is evident that, with more stringent p-value, the
significant portion (741) of about 11500 genes are showing features of
EMT genes
model_pvalues <- data.frame(Gene_symbol = merged_hits$Gene_symbol,
pvalue = merged_hits$P.Value)
model_pvalues$color <- "black"
model_pvalues$color[model_pvalues$pvalue < 0.0005] <- "orange"
SPP1 <- normalized_count_data$Gene_symbol[which(normalized_count_data$Gene_symbol == "SPP1")]
model_pvalues$color[model_pvalues$Gene_symbol== SPP1] <- "red"
plot(model_pvalues$pvalue,
col = model_pvalues$color,
xlab = "Number of Genes within the Dataset",
ylab ="P-value",
main="P value distribution of EMT Genes")
points(model_pvalues[which(model_pvalues$Gene_symbol == "SPP1"), 1:2],
pch = 20, col="red", cex=1.5)
legend(0, 1, legend=c("SPP1"), fill=c("red"))

Part 11: Clustered Heatmap with More Stringent Values
With more stringent gene size I was able to see cleaner difference
between GLI2 and the control cells. The clustered genes are the
symmetric each other across the diagonals. The high expression showing
genes on the GLI2’s side is lower on the EV’ side. Top hits are assessed
on the stringent p-value of 0.0005. The difference between the first and
the latest heatmap shows there is significant difference in terms of
gene expression whose expression is represented for each respective
Treatments
top_hits <- merged_hits$Gene_symbol[merged_hits$P.Value < 0.0005]
heatmap_matrix_tophits <- t(scale(t(heatmap_matrix[which(rownames(heatmap_matrix)
%in% top_hits),])))
if(min(heatmap_matrix_tophits) == 0){
heatmap_col = circlize::colorRamp2(c( 0, max(heatmap_matrix_tophits)),
c( "white", "purple"))
} else{
heatmap_col = circlize::colorRamp2(c(min(heatmap_matrix_tophits), 0,
max(heatmap_matrix_tophits)), c("darkgreen", "white", "purple"))
}
latest_heatmap <- ComplexHeatmap::Heatmap(as.matrix(heatmap_matrix_tophits),
show_row_dend = TRUE, show_column_dend = TRUE, col=heatmap_col,
show_column_names = TRUE, show_row_names = FALSE, show_heatmap_legend = TRUE)
latest_heatmap

first_heatmap

Part 12: Dataset Filtering and Data Extracting
The previously extracted GSE131222 data from gene omnibus expression
(GEO) is extracted separately. The low count portions of the data
filtered and a new matrix was created.
data = GEOquery::getGEOSuppFiles("GSE131222")
trying URL 'https://ftp.ncbi.nlm.nih.gov/geo/series/GSE131nnn/GSE131222/suppl//GSE131222_YAPCrtta-EV_GLI2_Adams.txt.gz?tool=geoquery'
Content type 'application/x-gzip' length 875595 bytes (855 KB)
==================================================
downloaded 855 KB
datanames = rownames(data)
GLI2_exp =read.delim(datanames[1],header=TRUE,check.names = FALSE)
count_per_ms = edgeR::cpm(GLI2_exp[,3:8])
rownames(count_per_ms) <- GLI2_exp[,2]
rows_filtered = rowSums(count_per_ms >1) >= 6
GLI2_exp_filtered = GLI2_exp[rows_filtered,]
filtered_GLI2_matrix <- as.matrix(GLI2_exp_filtered[,3:8])
rownames(filtered_GLI2_matrix) <- GLI2_exp_filtered$gene
head(GLI2_exp_filtered)[1:8]
Part 13: Grouping Based on the Cell Types
The similar grouping was done previously. However this time
dispersion values, normalization factors and differential expression
model fitting is applied to the samples of GLI2 treatments.
grouped_treatments <- data.frame(lapply(colnames(GLI2_exp_filtered)[3:8],
FUN=function(x){unlist(strsplit(x, split = "[0-9]"))[c(1)]}))
colnames(grouped_treatments) <- colnames(GLI2_exp)[3:8]
rownames(grouped_treatments) <- c("cell_type")
grouped_treatments_normalized <- data.frame(t(grouped_treatments))
d = edgeR::DGEList(counts=filtered_GLI2_matrix, group = grouped_treatments_normalized$cell_type)
model_design_celltypes <- model.matrix(~grouped_treatments_normalized$cell_type+0)
d <- edgeR::estimateDisp(d, model_design_celltypes)
d <- edgeR::calcNormFactors(d)
fit <- edgeR::glmQLFit(d, model_design_celltypes)
qlf_test.GLI2vsEV <- edgeR::glmQLFTest(fit, coef = "grouped_treatments_normalized$cell_typeYRG")
Part 14: Significant Results within the Fitted Model
With more stringent p-value I was able to assess the critical
threshold for the expression threshold. I set the p-value as 0.0005. I
decided to put it by adjusting and observing any difference. The
difference between p-value 0.005 and p-value 0.0005 is one. This means
this p-value is safe to assume as a threshold for significance among
these differentially expressing genes.
qlf_top_hits <- edgeR::topTags(qlf_test.GLI2vsEV,sort.by = "PValue", n = nrow(filtered_GLI2_matrix))
head(qlf_top_hits)
Coefficient: grouped_treatments_normalized$cell_typeYRG
length(which(qlf_top_hits$table$PValue < 0.0005))
[1] 2434
length(which(qlf_top_hits$table$FDR < 0.0005))
[1] 2433
length(which(qlf_top_hits$table$logFC < 0))
[1] 11527
Part 15: Thresholded Gene List and Final EMT Gene Detection
The threshold was calculated and based its value I assessed the how
many genes actually show traits similar to GLI2. I used P value 1 to
eliminate significant portion of the differentially expressed genes. I
did not use the LogFC to distinguish between EMT GLI2 vs non-EMT GLI2,
because all of logFC values are negative. This indicates there is always
up regulation after the Dox treatment and GLI2 expression is always
higher than the control. Pretty high confidence.
qlf_tophits_withgn <- merge(GLI2_exp[,1:1], qlf_top_hits, by.y=0,by.x=1,all.y=TRUE)
colnames(qlf_tophits_withgn) <- c("Gene_symbol", "logFC", "logCPM","F", "PValue", "FDR")
qlf_tophits_withgn[,"logarithmic"] <- (-log(qlf_tophits_withgn$PValue))
qlf_tophits_withgn <- qlf_tophits_withgn[order(qlf_tophits_withgn$Gene_symbol),]
GLI2_emt_Genes <- qlf_tophits_withgn$Gene_symbol[which(qlf_tophits_withgn$PValue < 0.0005
& qlf_tophits_withgn$logFC < 0)]
GLI2_non_emtgenes <- qlf_tophits_withgn$Gene_symbol[which(qlf_tophits_withgn$PValue == 1)]
write.table(x=GLI2_emt_Genes, file = file.path(getwd(),"data","GLI2_emt_Genes.txt"),
sep = "/", row.names = FALSE, col.names = FALSE, quote = FALSE)
write.table(x=GLI2_non_emtgenes, file = file.path(getwd(),"data","GLI2_non_emtgenes.txt"),
sep = "/", row.names = FALSE, col.names = FALSE, quote = FALSE)
Part 16: GProfiler for Upregulation and Downregulation pathway
analysis
The GProfiler analysis includes BH correction methods (FDR). I
sticked using the same method because I used the same type of method on
my previous analysis on FDR portion. For both upregualted and the
downregulated genes I have used GO:BP
(2022-12-04), Reactome, and WikiPathways( for annotation. These
annotations allows for better asessment of my Upregualted genes in terms
of defining the biologic pathways they are invovled in.
Upregulated_genes <- read.table(file=file.path(getwd(),"data" ,"GLI2_emt_Genes.txt"),header = TRUE, stringsAsFactors = FALSE, check.names = FALSE)
Upregulated_genes <- Upregulated_genes[4:nrow(Upregulated_genes),]
Upregulated_Gprofiler_validated <- gprofiler2::gost(query = Upregulated_genes,
organism = "hsapiens",
exclude_iea = TRUE,
sources = c("GO:BP", "REAC", "WP"),
correction_method = "fdr",
ordered_quer = FALSE,
)
Continuing Analysis
Downregulated_genes <- read.table(file=file.path(getwd(),"data" ,"GLI2_non_emtgenes.txt"),header = TRUE, stringsAsFactors = FALSE, check.names = FALSE)
Downregulated_genes <- Downregulated_genes[13:nrow(Downregulated_genes),]
Downregulated_Gprofiler_validated <- gprofiler2::gost(query = Downregulated_genes,
organism = "hsapiens",
exclude_iea = TRUE,
correction_method = "fdr",
ordered_quer = FALSE,
source = c("GO:BP", "REAC", "WP"))
Part 17: Subsetting the Gprofiler downregulated and upregualted
genes
After subsetting I do have 771 genes that are down regulated. Down
regualted genes are invovled in common biological pathways that are not
involved in cancerous activities.
Downregulated_genes_filtered <- data.frame(
term_name = Downregulated_Gprofiler_validated$result$term_name[Downregulated_Gprofiler_validated$result$term_size < 200 & Downregulated_Gprofiler_validated$result$term_size > 1],
term_id = Downregulated_Gprofiler_validated$result$term_id[Downregulated_Gprofiler_validated$result$term_size < 200 &
Downregulated_Gprofiler_validated$result$term_size > 1],
source = Downregulated_Gprofiler_validated$result$source[Downregulated_Gprofiler_validated$result$term_size < 200 &
Downregulated_Gprofiler_validated$result$term_size > 1]
)
length(Downregulated_genes_filtered$term_name)
knitr::kable(head(Downregulated_genes_filtered, 10), format = "html")
For Upregulation
After subsetting I do have 1128 genes that are down regulated. Up
regualted genes are mostly invovled in cancer activity. Most of the
pathwyas are quite invovled in cancerous activty. There is a lot
apoptosis and programmed cell death activities.
Upregulated_genes_filtered <- data.frame(
term_name = Upregulated_Gprofiler_validated$result$term_name[Upregulated_Gprofiler_validated$result$term_size < 200 & Upregulated_Gprofiler_validated$result$term_size > 1],
term_id = Upregulated_Gprofiler_validated$result$term_id[Upregulated_Gprofiler_validated$result$term_size < 200 &
Upregulated_Gprofiler_validated$result$term_size > 1],
source = Upregulated_Gprofiler_validated$result$source[Upregulated_Gprofiler_validated$result$term_size < 200 &
Upregulated_Gprofiler_validated$result$term_size > 1]
)
length(Upregulated_genes_filtered$term_name)
knitr::kable(head(Upregulated_Gprofiler_validated, 10), format = "html")
Part 18: Visualizations of the upregualted and the downregulated
genes
gprofiler2::gostplot(Upregulated_Gprofiler_validated) %>% plotly::layout(title = "Upregulated genes ", font = list(size = 10))
Continuing
gprofiler2::gostplot(Downregulated_Gprofiler_validated) %>% plotly::layout(title = "Downregulated genes ", font = list(size = 10))
Part 19: GProfiler Analyses for the merged dataset
Complete_Gprofiler_Analyses <- gprofiler2::gost(query = merged_hits$Gene_symbol,
organism = "hsapiens",
exclude_iea = TRUE,
correction_method = "fdr",
sources = c("GO:BP", "REAC", "WP"))
Continuing
gprofiler2::gostplot(Complete_Gprofiler_Analyses) %>% plotly::layout(title = "Complete plot plot", font = list(size = 10))
Part 20:Interpretation
Do the over-representation results support conclusions or mechanism
discussed in the original paper ?
Yes the over-representation results we find is correlated to the
conclusion the authors make. They conclude that genes having higher GLI2
expression, more differentially expressed, are more possible to be EMT
genes. Additionally, we found there is always higher expression on GLI2
treatments given this is a strong oncogene acting in basal-sub-type
switching triggering EMT switching. As it is obvious from the
visualization the upregualted genes are more clustered and are much more
in the downregualted genes This supports the hypothesis of authors,
concluding the EMT genes to be higher expression than that of the
downregualted genes.
Can you find evidence, i.e. publications, to support some of the
results that you see. How does this evidence support your results ?
The paper (Pasca di Magliano et al.,2006) has already indicated
increase expression of GLI2 can lead to SHH gene reduction. This gene
has been known to be an oncogene associated with basal-sub-type
switching in PDAC. They activate GLI2 constantly which has the same
expected outcome in our data set having GLI2 expressing vectors with
constant Dox treatment. In conclusion these two paper findings correlate
each other. They show that the EMT genes to be abundant in their
biological functions and their pathway invovlement.
References
Adams, Christina R, Htet Htwe Htwe, Timothy Marsh, Aprilgate L Wang,
Megan L Montoya, Lakshmipriya Subbaraj, Aaron D Tward, Nabeel Bardeesy,
and Rushika M Perera. 2019. “Transcriptional Control of Subtype
Switching Ensures Adaptation and Growth of Pancreatic Cancer.”
Elife 8: e45313.
Allaire, JJ, Yihui Xie, Jonathan McPherson, Javier Luraschi, Kevin
Ushey, Aron Atkins, Hadley Wickham, Joe Cheng, Winston Chang, and
Richard Iannone. 2021.
rmarkdown: Dynamic
Documents for R.
https://github.com/rstudio/rmarkdown.
Davis, S., and P. Meltzer. 2007. “GEOquery: A Bridge Between the
Gene Expression Omnibus (GEO) and BioConductor.”
Bioinformatics 14: 1846–47.
Durinck, S., P. Spellman, E. Birney, and W. Huber. 2009. “Mapping
Identifiers for the Integration of Genomic Datasets with the
r/Bioconductor Package biomaRt.” Nature Protocols 4:
1184–91.
Gu, Zuguang. 2022. “Complex Heatmap Visualization.”
iMeta 1 (3): e43.
Gu, Zuguang, Lei Gu, Roland Eils, Matthias Schlesner, and Benedikt
Brors. 2014. “Circlize Implements and Enhances Circular
Visualization in r.” Bioinformatics 30 (19): 2811–12.
Magliano, Marina Pasca di, Shigeki Sekine, Alexandre Ermilov, Jenny
Ferris, Andrzej A Dlugosz, and Matthias Hebrok. 2006.
“Hedgehog/Ras Interactions Regulate Early Stages of Pancreatic
Cancer.” Genes & Development 20 (22): 3161–73.
R Core Team. 2022.
R: A Language and Environment for Statistical
Computing. Vienna, Austria: R Foundation for Statistical Computing.
https://www.R-project.org/.
Ritchie, Matthew E, Belinda Phipson, DI Wu, Yifang Hu, Charity W Law,
Wei Shi, and Gordon K Smyth. 2015. “Limma Powers Differential
Expression Analyses for RNA-Sequencing and Microarray Studies.”
Nucleic Acids Research 43 (7): e47–47.
Robinson, M. D., McCarthy DJ, and G. K. Smyth. 2010. “edgeR: A
Bioconductor Package for Differential Expression Analysis of Digital
Gene Expression Data.” Bioinformatics 26: 139–40.
LS0tCnRpdGxlOiAiQTJfTWV0eXVNZWxrb255YW4ucm1kIgpkYXRlOiAiMjAyMy0wMy0wOCIKYXV0aG9yOiAiTWV0eXUgTWVsa29ueWFuIgpiaWJsaW9ncmFwaHk6IEEyLmJpYgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwotLS0KCiogQmlvY29uZHVjdG9yIChAZHVyaW5jazIwMDlhKQoqIFIgbGFuZ3VhZ2UgKEByKQoqIEFydGljbGUgKEBhZGFtczIwMTl0cmFuc2NyaXB0aW9uYWwpCiogUm1hcmtkb3duIChAQWxsYWlyZV9ybWFya2Rvd25fRHluYW1pY19Eb2N1bWVudHNfMjAyMSkKKiBlZGdlUiAoQHJvYmluc29uMjAxMGEpCiogR0VPcXVlcnkgKEBkYXZpczIwMDdhKQoqIFNISCAoQGRpMjAwNmhlZGdlaG9nKQoqIExpbW1hIChAcml0Y2hpZTIwMTVsaW1tYSkKKiBDb21wbGV4SGVhdE1hcCAoQGd1MjAyMmNvbXBsZXgpCiogQ2lyY2xpemUgKEBndTIwMTRjaXJjbGl6ZSkKCiMjIyBJbnN0YWxsaW5nIERlcGVuZGVuY2llcwpgYGB7ciBtZXNzYWdlPUZBTFNFfQppZiAoIXJlcXVpcmVOYW1lc3BhY2UoIkJpb2NNYW5hZ2VyIiwgcXVpZXRseSA9IFRSVUUpKXsKICBpbnN0YWxsLnBhY2thZ2VzKCJCaW9jTWFuYWdlciIpfQppZiAoIXJlcXVpcmVOYW1lc3BhY2UoImVkZ2VSIiwgcXVpZXRseSA9IFRSVUUpKXsKICBCaW9jTWFuYWdlcjo6aW5zdGFsbCgiZWRnZVIiKX0KaWYgKCFyZXF1aXJlTmFtZXNwYWNlKCJHRU9xdWVyeSIsIHF1aWV0bHkgPSBUUlVFKSl7CiAgQmlvY01hbmFnZXI6Omluc3RhbGwoIkdFT3F1ZXJ5Iil9CmlmICghcmVxdWlyZU5hbWVzcGFjZSgiQ29tcGxleEhlYXRtYXAiLCBxdWlldGx5ID0gVFJVRSkpewogIEJpb2NNYW5hZ2VyOjppbnN0YWxsKCJDb21wbGV4SGVhdG1hcCIpfQppZiAoIXJlcXVpcmVOYW1lc3BhY2UoImxpbW1hIiwgcXVpZXRseSA9IFRSVUUpKXsKICBCaW9jTWFuYWdlcjo6aW5zdGFsbCgibGltbWEiKX0KaWYgKCFyZXF1aXJlTmFtZXNwYWNlKCJFeHByZXNzaW9uU2V0IiwgcXVpZXRseSA9IFRSVUUpKXsKICBCaW9jTWFuYWdlcjo6aW5zdGFsbCgiRXhwcmVzc2lvblNldCIpfQppZiAgKCFyZXF1aXJlTmFtZXNwYWNlKCJjaXJjbGl6ZSIsIHF1aWV0bHkgPSBUUlVFKSl7CiAgQmlvY01hbmFnZXI6Omluc3RhbGwoImNpcmNsaXplIil9CmlmICghcmVxdWlyZU5hbWVzcGFjZSgiZ3Byb2ZpbGVyMiIsIHF1aWV0bHkgPSBUUlVFKSkKICAgIEJpb2NNYW5hZ2VyOjppbnN0YWxsKCJncHJvZmlsZXIyIikKaWYgKCFyZXF1aXJlTmFtZXNwYWNlKCJrYWJsZUV4dHJhIiwgcXVpZXRseSA9IFRSVUUpKQogICAgQmlvY01hbmFnZXI6Omluc3RhbGwoImthYmxlRXh0cmEiKQppZiAoIXJlcXVpcmVOYW1lc3BhY2UoInBsb3RseSIsIHF1aWV0bHkgPSBUUlVFKSkKICAgIEJpb2NNYW5hZ2VyOjppbnN0YWxsKCJwbG90bHkiKQppZiAoIXJlcXVpcmVOYW1lc3BhY2UoImRwbHlyIiwgcXVpZXRseSA9IFRSVUUpKQogICAgQmlvY01hbmFnZXI6Omluc3RhbGwoImRwbHlyIikKbGlicmFyeShkcGx5cikKbGlicmFyeShwbG90bHkpCgpgYGAKIyMjIFBhcnQgMTogTG9hZGluZyB0aGUgbm9ybWFsaXplZCBnZW5lIGRhdGEKVGhlIG5vcm1hbGl6ZWQgZGF0YSBoYXMgYWxyZWFkeSBiZWVuIHdyaXR0ZW4gaW50byBhIHRleHQgZmlsZSBieSB0aGUgcHJldmlvdXMKQXNzaWdubWVudCAxLiBGb3IgYmV0dGVyIGFzc2Vzc21lbnQsIEkgaGF2ZSBpbmRpY2F0ZWQgaXQgb24gdGhlIGZpbGUgdXBsb2FkZWQuCmBgYHtyIGV2YWw9VFJVRSwgbWVzc2FnZT1GQUxTRX0Kbm9ybWFsaXplZF9jb3VudF9kYXRhIDwtIHJlYWQudGFibGUoZmlsZT1maWxlLnBhdGgoZ2V0d2QoKSwgIm5vcm1hbGl6ZWRfY291bnRzX2Fubm90YXRlZCIpCiwgaGVhZGVyID0gVFJVRSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLCBjaGVjay5uYW1lcyA9IEZBTFNFICkKCmtuaXRyOjprYWJsZShub3JtYWxpemVkX2NvdW50X2RhdGFbMToxMCwxOjddLCB0eXBlPSJwaXBlIikKYGBgCiMjIyBQYXJ0IDI6IERlZmluaW5nIFBvcnRpb25zIG9mIHRoZSBIZWF0bWFwIE1hdHJpeCA8YnI+CkkgYW0gZGVmaW5pbmcgdGhlIGVsZW1lbnRzIG9mIHRoZSBub3JtYWxpemVkIGRhdGEgbWF0cml4IHdoaWNoIEkgd2lsbCAKYmUgdXNpbmcgZm9yIHRoZSBoZWF0bWFwIGxhdGVyLgpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmhlYXRtYXBfbWF0cml4IDwtIG5vcm1hbGl6ZWRfY291bnRfZGF0YVssMjo3XQpjb2xuYW1lcyhub3JtYWxpemVkX2NvdW50X2RhdGEpWzFdIDwtICJHZW5lX3N5bWJvbCIKcm93bmFtZXMoaGVhdG1hcF9tYXRyaXgpIDwtIG5vcm1hbGl6ZWRfY291bnRfZGF0YSRHZW5lX3N5bWJvbApjb2xuYW1lcyhoZWF0bWFwX21hdHJpeCkgPC0gY29sbmFtZXMobm9ybWFsaXplZF9jb3VudF9kYXRhWywyOjddKQpoZWF0bWFwX21hdHJpeCA8LSB0KHNjYWxlKHQoaGVhdG1hcF9tYXRyaXgpKSkKYGBgCiMjIyBQYXJ0IDM6IENyZWF0aW5nIEhlYXRtYXAgPGJyPgpUaGUgaGVhdG1hcCB1c2VzIGRpZmZlcmVudCBjb2xvcnMgZm9yIHRoZSBleHByZXNzaW9uIGRhdGEuIFRoZSBoZWF0bWFwIGhhcyBtYW55IApnZW5lcyBjbHVzdGVyZWQgYmFzZWQgb24gdGhlaXIgZXhwcmVzc2lvbiBhdCBkaWZmZXJlbnQgbGV2ZWxzIHN1Y2ggYXMgY29udHJvbCAKKEVBMSxFQTIsRUIxKSBvciB0aGUgY2VsbHMgdHJlYXRlZCB3aXRoIEdMSTIgKEcxQSxHMkEsRzFCKS4KYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmlmKG1pbihoZWF0bWFwX21hdHJpeCkgPT0gMCl7CiAgIGhlYXRtYXBfY29sID0gY2lyY2xpemU6OmNvbG9yUmFtcDIoYyggMCwgbWF4KGhlYXRtYXBfbWF0cml4KSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoIndoaXRlIiwgInB1cnBsZSIpKQp9IGVsc2UgewogIGhlYXRtYXBfY29sID0gY2lyY2xpemU6OmNvbG9yUmFtcDIoYyhtaW4oaGVhdG1hcF9tYXRyaXgpLCAwLAogICAgICAgICBtYXgoaGVhdG1hcF9tYXRyaXgpKSwgYygiZGFya2dyZWVuIiwgIndoaXRlIiwgInB1cnBsZSIpKQp9CmZpcnN0X2hlYXRtYXAgPC0gQ29tcGxleEhlYXRtYXA6OkhlYXRtYXAoYXMubWF0cml4KGhlYXRtYXBfbWF0cml4KSwKICAgICBzaG93X3Jvd19kZW5kID0gVFJVRSwgc2hvd19jb2x1bW5fZGVuZCA9IFRSVUUsCiAgICAgY29sPWhlYXRtYXBfY29sLCBzaG93X2NvbHVtbl9uYW1lcyA9IFRSVUUsCiAgICAgc2hvd19yb3dfbmFtZXMgPSBGQUxTRSwgc2hvd19oZWF0bWFwX2xlZ2VuZCA9IFRSVUUpCmZpcnN0X2hlYXRtYXAKYGBgCiMjIyBQYXJ0IDQ6IFNQUDEgRU1UIEdlbmVzLUNvbmNsdXNpb24ganVzdGlmaWNhdGlvbiA8YnI+ClNQUDEgaXMgYW4gRU1UIGdlbmVzIEl0IHNob3dzIGhpZ2hlciBleHByZXNzaW9uIHdoZW4gdHJlYXRlZCB3aXRoIEdMSTIgY29tcGFyZSAKdG8gZW1wdHkgdmVjdG9yIGNvbnRyb2wgY2VsbHMgKEVWKS4gVGhpcyBoYXMgYmVlbiBhbHNvIHByb3ZlZCBieSB0aGUgYXV0aG9ycy4KSG93ZXZlciwgaW5kaWNhdGluZyB0aGlzIGFnYWluIHdvdWxkIHN0cmVuZ3RoZW4gdGhlIGh5cG90aGVzaXMgY29ycmVzcG9uZGluZyB0bwpEb3ggdHJlYXRlZCBjZWxscyBoYXZpbmcgR0xJMiB2ZWN0b3Igc2hvdyBoaWdoZXIgRU1UIGdlbmUgZXhwcmVzc2lvbiAgYXMKb3Bwb3NlZCB0byBjb250cm9scyBoYXZpbmcgZW1wdHkgdmVjdG9yIHNob3dpbmcgbGVzcyBleHByZXNzaW9uIG9mIHRoZSBnZW5lcy4KYGBge3IgbWVzc2FnZT1GQUxTRX0KR0xJMl90cmVhdG1lbnRfc2FtcGxlcyA8LSBncmVwKGNvbG5hbWVzKG5vcm1hbGl6ZWRfY291bnRfZGF0YSkscGF0dGVybiA9ICJcXEciKQpFVl90cmF0bWVudF9zYW1wbGVzIDwtIGdyZXAoY29sbmFtZXMobm9ybWFsaXplZF9jb3VudF9kYXRhKSxwYXR0ZXJuID0gIlxcRSIpCmdlbmVfb2ZfaW50ZXJlc3QgPC0gd2hpY2gobm9ybWFsaXplZF9jb3VudF9kYXRhJEdlbmVfc3ltYm9sID09ICJTUFAxIikKCllBUENfR0xJMl9zYW1wbGVzIDwtIHQobm9ybWFsaXplZF9jb3VudF9kYXRhW2dlbmVfb2ZfaW50ZXJlc3QsNTo3XSkKY29sbmFtZXMoWUFQQ19HTEkyX3NhbXBsZXMpIDwtIGMoIkdMSTJfdmVjdG9yX2NlbGxzIikKCllBUENfRVZfc2FtcGxlcyA8LSB0KG5vcm1hbGl6ZWRfY291bnRfZGF0YVtnZW5lX29mX2ludGVyZXN0LDI6NF0pCmNvbG5hbWVzKFlBUENfRVZfc2FtcGxlcykgPC0gYygiRW1wdHlfVmVjdG9yX2NlbGxzIikKCllBUENfR0xJMl9zYW1wbGVzCllBUENfRVZfc2FtcGxlcwpgYGAKIyMjIFBhcnQgNTogVC10ZXN0IGJldHdlZW4gRVYgYW5kIEdMSTIKR0xJMiB0cmVhdGVkIGNlbGxzIGFyZSBkaWZmZXJlbnQgaW4gdGVybXMgb2YgdGhlaXIgZXhwcmVzc2lvbiBmcm9tIHRoZSAKZW1wdHkgdmVjdG9yIGNlbGxzLiBQIHZhbHVlICgwLjAzMTM1KSA8IDAuMDUuIEluZGVlZCB0aGlzIHNob3dzIHRoZXJlIGlzIApzaWduaWZpY2FudCBkaWZmZXJlbmNlLiBIb3dldmVyLCB0aGlzIHJlcXVpcmVzIHRvIHNlZSBpZiBHTEkyIHRyZWF0bWVudHMgCnNob3cgZGlmZmVyZW5jZSBhbW9uZyBvbmUgYW5vdGhlciBzbyB0aGUgY29udHJvbCBjZWxscy4KYGBge3IgbWVzc2FnZT1GQUxTRX0KdC50ZXN0KHg9dChZQVBDX0dMSTJfc2FtcGxlcyksIHk9dChZQVBDX0VWX3NhbXBsZXMpKQpgYGAKIyMjIFBBUlQgNjogTURTIFBsb3QgZm9yIFNhbXBsZSBDbHVzdGVyaW5nClRoZSBNRFMgcGxvdCBhbGxvd2VkIHRvIHZpc3VhbGl6ZSB0aGUgZGlmZmVyZW5jZSB3aXRoaW4gdGhlIGRpZmZlcmVudCBjZWxsIHR5cGVzCkVhcmxpZXIgZXhhbXBsZXMgb2YgTURTIHBsb3Qgc2hvd2VkIHNpbWlsYXIgcmVzdWx0cy4gSSBoeXBvdGhlc2l6ZSB0aGF0IEdMSTIKZXhwcmVzc2lvbiBpcyBoaWdoZXIgdGhhbiBjb250cm9sIGNlbGwncyBleHByZXNzaW9uIGxldmVscyBkdWUgdG8gRE9YIGluZHVjdGlvbgpvZiBFTVQgZ2VuZXMuIEluIGdlbmVyYWwgSSBoYXZlIG9ic2VydmVkIEdsaTIgY2VsbHMgdG8gYmUgbGVzcyBjbHVzdGVyZWQsIApkdWUgdG8gaGlnaGVyIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFtb25nIEdMSTIgY2VsbHMuCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CmxpbW1hOjpwbG90TURTKGhlYXRtYXBfbWF0cml4LGNvbD1jKHJlcCgiZGFya2dyZWVuIiwzKSwgcmVwKCJibHVlIiwzKSkpCmBgYAojIyMgUGFydCA3OiBNb2RlbCBCdWlsZGluZyBvZiBHTEkyIGV4cHJlc3Npb24gc3RhdHVzClRoZSBtb2RlbCBJIGFtIGJ1aWxkaW5nIGlzIGJhc2VkIHVwb24gR0xJMiBleHByZXNzaW9uIHN0YXR1cyBvZiBnZW5lcyB0aGF0CmFyZSBzaG93aW5nIGhpZ2hlciBleHByZXNzaW9uIHdpdGggc2lnbmlmaWNhbnQgaW5kaWNhdGlvbnMgb2YgdGhlIGRpZmZlcmVudGlhbCAKZXhwcmVzc2lvbi4KYGBge3IgbWVzc2FnZT1GQUxTRX0Kc2FtcGxlcyA8LSBkYXRhLmZyYW1lKGxhcHBseShjb2xuYW1lcyhub3JtYWxpemVkX2NvdW50X2RhdGEpWzI6N10sCiAgICAgICAgICAgRlVOPWZ1bmN0aW9uKHgpe3VubGlzdChzdHJzcGxpdCh4LCBzcGxpdCA9ICJbMC05XSIpKVtjKDEpXX0pKQoKY29sbmFtZXMoc2FtcGxlcykgPC0gY29sbmFtZXMoY29sbmFtZXMobm9ybWFsaXplZF9jb3VudF9kYXRhKVsyOjddKQpyb3duYW1lcyhzYW1wbGVzKSA8LSBjKCJUcmVhdG1lbnRzIikKc2FtcGxlcyA8LSBkYXRhLmZyYW1lKHQoc2FtcGxlcykpCmtuaXRyOjprYWJsZShzYW1wbGVzLCB0eXBlID0gInBpcGUiKSAKCllSR19tb2RlbCA8LSBtb2RlbC5tYXRyaXgoIH4gc2FtcGxlcyRUcmVhdG1lbnRzKQprbml0cjo6a2FibGUoWVJHX21vZGVsWzE6NixdLCB0eXBlID0gInBpcGUiKQpgYGAKIyMjIFBhcnQgODogTW9kZWwgRml0dGluZyBhbmQgRGlmZmVyZW50aWFsIEV4cHJlc3Npb24gQ2FsY3VsYXRpb24KVGhlIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGRhdGEgbWF0cml4IGNvcnJlc3BvbmRpbmcgdG8gZ2VuZSBzeW1ib2xzIHdlcmUgbWVyZ2VkCndpdGggdGhlIG1hdHJpeCB0aGF0IGhhcyB0aGUgZml0dGVkIG1vZGVsLiBUaGUgQmVuamFtaW4taG9jaGJlcmcgY29ycmVjdGlvbiAKbWV0aG9kIHdhcyBhcHBsaWVkIHRvIGFkanVzdCB0aGUgZXhwcmVzc2lvbiBkYXRhLgpgYGB7ciBtZXNzYWdlPUZBTFNFfQpleHByZXNzaW9uTWF0cml4IDwtIGFzLm1hdHJpeChub3JtYWxpemVkX2NvdW50X2RhdGFbLDI6N10pCnJvd25hbWVzKGV4cHJlc3Npb25NYXRyaXgpIDwtIG5vcm1hbGl6ZWRfY291bnRfZGF0YSRHZW5lX3N5bWJvbApjb2xuYW1lcyhleHByZXNzaW9uTWF0cml4KSA8LSBjb2xuYW1lcyhub3JtYWxpemVkX2NvdW50X2RhdGEpWzI6N10Kc2V0X2V4cHJlc3Npb25fbWF0cml4IDwtIEJpb2Jhc2U6OkV4cHJlc3Npb25TZXQoYXNzYXlEYXRhID0gZXhwcmVzc2lvbk1hdHJpeCkKCmZpdCA8LSBsaW1tYTo6bG1GaXQoc2V0X2V4cHJlc3Npb25fbWF0cml4LCBZUkdfbW9kZWwpCgpmaXRfQmF5ZXMgPC0gbGltbWE6OmVCYXllcyhmaXQsIHRyZW5kID0gVFJVRSkKCkJIX21ldGhvZF9maXQgPC0gbGltbWE6OnRvcFRhYmxlKGZpdF9CYXllcywKICAgICAgICAgICAgICAgICAgIGNvZWYgPSBuY29sKFlSR19tb2RlbCksCiAgICAgICAgICAgICAgICAgICBhZGp1c3QubWV0aG9kID0gIkJIIiwKICAgICAgICAgICAgICAgICAgIG51bWJlciA9IG5yb3coZXhwcmVzc2lvbk1hdHJpeCkpCgptZXJnZWRfaGl0cyA8LSBtZXJnZShub3JtYWxpemVkX2NvdW50X2RhdGEkR2VuZV9zeW1ib2wsCiAgICAgICAgICAgICAgICAgICAgIEJIX21ldGhvZF9maXQsCiAgICAgICAgICAgICAgICAgICAgIGJ5Lnk9MCxieS54PTEsCiAgICAgICAgICAgICAgICAgICAgIGFsbC55PVRSVUUpCgptZXJnZWRfaGl0cyA8LSBtZXJnZWRfaGl0c1tvcmRlcihtZXJnZWRfaGl0cyRQLlZhbHVlKSxdCmNvbG5hbWVzKG1lcmdlZF9oaXRzKSA8LSBjKCJHZW5lX3N5bWJvbCIsImxvZ0ZDIiwgIkF2ZUV4cHIiLCAidCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJQLlZhbHVlIiwiYWRqLlAuVmFsIiwgIkIiKQpyb3duYW1lcyhtZXJnZWRfaGl0cykgPC0gMTpucm93KG1lcmdlZF9oaXRzKQoKa25pdHI6OmthYmxlKG1lcmdlZF9oaXRzWzE6MTAsMTo3XSwgdHlwZSA9ICJwaXBlIiwgcm93Lm5hbWVzID0gRkFMU0UsKQpgYGAKIyMjIFBhcnQgOTogUC12YWx1ZSBBc3Nlc3NtZW50ClRoZSBwLXZhbHVlIHdhcyBhZGp1c3RlZCB0byBoYXZlIG1vcmUgc3RyaW5nZW50IHJlc3VsdHMuIE5vcm1hbGx5IHNpZ25pZmljYW50IApwLXZhbHVlIGlzIHNldCB0byAwLjA1LiBIb3dldmVyLCBJIHdhbnRlZCB0byBiZSBtb3JlIHN0cmluZ2VudCBvbiBteSByZXN1bHRzCmFuZCBpbmRpY2F0ZSB0aGUgc3BlY2lmaWMgRU1UIGdlbmVzLiBQcm9iYWJsZSBnZW5lcyBhcmUgNzQxLiBIb3dldmVyLAp0aGVyZSBhcmUgMjcgZ2VuZXMgdGhhdCBoYXZlIHNpZ25pZmljYW50IHBvdGVudGlhbCB0byBiZSBhbiBFTVQgZ2VuZS4KYGBge3IgbWVzc2FnZT1GQUxTRX0KbGVuZ3RoKHdoaWNoKG1lcmdlZF9oaXRzJFAuVmFsdWUgPCAwLjAwMDUpKQoKbGVuZ3RoKHdoaWNoKG1lcmdlZF9oaXRzJGFkai5QLlZhbCA8IDAuMDAwNSkpCmBgYAojIyMgUGFydCAxMDogTW9kZWwgVmlzdWFsaXphdGlvbiAKVGhpcyBwYXJ0IG9mIHRoaXMgYXNzaWdubWVudCBhaW1zIHRvIGRldGVjdCBTUFAxJ3Mgcm9sZSBvbiBob3cgR0xJMiBjZWxscyBhcmUKbW9yZSBkaWZmZXJlbnRseSBleHByZXNzZWQgYW5kIGRvIGhhdmUgaGlnaGVyIGRpZmZlcmVuY2UgdGhhbiB0aGUgY29udHJvbCBjZWxscy4KSXQgaXMgZXZpZGVudCB0aGF0LCB3aXRoIG1vcmUgc3RyaW5nZW50IHAtdmFsdWUsIHRoZSBzaWduaWZpY2FudCBwb3J0aW9uICg3NDEpCm9mIGFib3V0IDExNTAwIGdlbmVzIGFyZSBzaG93aW5nIGZlYXR1cmVzIG9mIEVNVCBnZW5lcwpgYGB7ciAgbWVzc2FnZT1GQUxTRX0KbW9kZWxfcHZhbHVlcyA8LSBkYXRhLmZyYW1lKEdlbmVfc3ltYm9sID0gbWVyZ2VkX2hpdHMkR2VuZV9zeW1ib2wsIApwdmFsdWUgPSBtZXJnZWRfaGl0cyRQLlZhbHVlKQoKbW9kZWxfcHZhbHVlcyRjb2xvciA8LSAiYmxhY2siCm1vZGVsX3B2YWx1ZXMkY29sb3JbbW9kZWxfcHZhbHVlcyRwdmFsdWUgPCAwLjAwMDVdIDwtICJvcmFuZ2UiCiAgICAKU1BQMSA8LSBub3JtYWxpemVkX2NvdW50X2RhdGEkR2VuZV9zeW1ib2xbd2hpY2gobm9ybWFsaXplZF9jb3VudF9kYXRhJEdlbmVfc3ltYm9sID09ICJTUFAxIildCm1vZGVsX3B2YWx1ZXMkY29sb3JbbW9kZWxfcHZhbHVlcyRHZW5lX3N5bWJvbD09IFNQUDFdIDwtICJyZWQiCgpwbG90KG1vZGVsX3B2YWx1ZXMkcHZhbHVlLAogICAgIGNvbCA9IG1vZGVsX3B2YWx1ZXMkY29sb3IsCiAgICAgeGxhYiA9ICJOdW1iZXIgb2YgR2VuZXMgd2l0aGluIHRoZSBEYXRhc2V0IiwKICAgICB5bGFiID0iUC12YWx1ZSIsCiAgICAgbWFpbj0iUCB2YWx1ZSBkaXN0cmlidXRpb24gb2YgRU1UIEdlbmVzIikKCnBvaW50cyhtb2RlbF9wdmFsdWVzW3doaWNoKG1vZGVsX3B2YWx1ZXMkR2VuZV9zeW1ib2wgPT0gIlNQUDEiKSwgMToyXSwKICAgICAgIHBjaCA9IDIwLCBjb2w9InJlZCIsIGNleD0xLjUpCmxlZ2VuZCgwLCAxLCBsZWdlbmQ9YygiU1BQMSIpLCBmaWxsPWMoInJlZCIpKQpgYGAKIyMjIFBhcnQgMTE6IENsdXN0ZXJlZCBIZWF0bWFwIHdpdGggTW9yZSBTdHJpbmdlbnQgVmFsdWVzCldpdGggbW9yZSBzdHJpbmdlbnQgZ2VuZSBzaXplIEkgd2FzIGFibGUgdG8gc2VlIGNsZWFuZXIgZGlmZmVyZW5jZSBiZXR3ZWVuIEdMSTIKYW5kIHRoZSBjb250cm9sIGNlbGxzLiBUaGUgY2x1c3RlcmVkIGdlbmVzIGFyZSB0aGUgc3ltbWV0cmljIGVhY2ggb3RoZXIgYWNyb3NzCnRoZSBkaWFnb25hbHMuIFRoZSBoaWdoIGV4cHJlc3Npb24gc2hvd2luZyBnZW5lcyBvbiB0aGUgR0xJMidzIHNpZGUgaXMgbG93ZXIgb24gCnRoZSBFVicgc2lkZS4gVG9wIGhpdHMgYXJlIGFzc2Vzc2VkIG9uIHRoZSBzdHJpbmdlbnQgcC12YWx1ZSBvZiAwLjAwMDUuClRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGZpcnN0IGFuZCB0aGUgbGF0ZXN0IGhlYXRtYXAgc2hvd3MgdGhlcmUgaXMgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSAKaW4gdGVybXMgb2YgZ2VuZSBleHByZXNzaW9uIHdob3NlIGV4cHJlc3Npb24gaXMgcmVwcmVzZW50ZWQgZm9yIGVhY2ggcmVzcGVjdGl2ZSBUcmVhdG1lbnRzCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CnRvcF9oaXRzIDwtIG1lcmdlZF9oaXRzJEdlbmVfc3ltYm9sW21lcmdlZF9oaXRzJFAuVmFsdWUgPCAwLjAwMDVdCmhlYXRtYXBfbWF0cml4X3RvcGhpdHMgPC0gdChzY2FsZSh0KGhlYXRtYXBfbWF0cml4W3doaWNoKHJvd25hbWVzKGhlYXRtYXBfbWF0cml4KSAKICAgICAgICAgICAgICAgICAgICAgICAlaW4lIHRvcF9oaXRzKSxdKSkpCgppZihtaW4oaGVhdG1hcF9tYXRyaXhfdG9waGl0cykgPT0gMCl7CmhlYXRtYXBfY29sID0gY2lyY2xpemU6OmNvbG9yUmFtcDIoYyggMCwgbWF4KGhlYXRtYXBfbWF0cml4X3RvcGhpdHMpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyggIndoaXRlIiwgInB1cnBsZSIpKQp9IGVsc2V7CmhlYXRtYXBfY29sID0gY2lyY2xpemU6OmNvbG9yUmFtcDIoYyhtaW4oaGVhdG1hcF9tYXRyaXhfdG9waGl0cyksIDAsCiAgICAgbWF4KGhlYXRtYXBfbWF0cml4X3RvcGhpdHMpKSwgYygiZGFya2dyZWVuIiwgIndoaXRlIiwgInB1cnBsZSIpKQp9CmxhdGVzdF9oZWF0bWFwIDwtIENvbXBsZXhIZWF0bWFwOjpIZWF0bWFwKGFzLm1hdHJpeChoZWF0bWFwX21hdHJpeF90b3BoaXRzKSwKc2hvd19yb3dfZGVuZCA9IFRSVUUsIHNob3dfY29sdW1uX2RlbmQgPSBUUlVFLCBjb2w9aGVhdG1hcF9jb2wsCnNob3dfY29sdW1uX25hbWVzID0gVFJVRSwgc2hvd19yb3dfbmFtZXMgPSBGQUxTRSwgc2hvd19oZWF0bWFwX2xlZ2VuZCA9IFRSVUUpCmxhdGVzdF9oZWF0bWFwCmZpcnN0X2hlYXRtYXAKYGBgCiMjIyBQYXJ0IDEyOiBEYXRhc2V0IEZpbHRlcmluZyBhbmQgRGF0YSBFeHRyYWN0aW5nClRoZSBwcmV2aW91c2x5IGV4dHJhY3RlZCBHU0UxMzEyMjIgZGF0YSBmcm9tIGdlbmUgb21uaWJ1cyBleHByZXNzaW9uIChHRU8pIGlzIApleHRyYWN0ZWQgc2VwYXJhdGVseS4gVGhlIGxvdyBjb3VudCBwb3J0aW9ucyBvZiB0aGUgZGF0YSBmaWx0ZXJlZCBhbmQgYSBuZXcKbWF0cml4IHdhcyBjcmVhdGVkLgpgYGB7ciBtZXNzYWdlPUZBTFNFfQpkYXRhID0gR0VPcXVlcnk6OmdldEdFT1N1cHBGaWxlcygiR1NFMTMxMjIyIikKZGF0YW5hbWVzID0gcm93bmFtZXMoZGF0YSkKCkdMSTJfZXhwID1yZWFkLmRlbGltKGRhdGFuYW1lc1sxXSxoZWFkZXI9VFJVRSxjaGVjay5uYW1lcyA9IEZBTFNFKQoKY291bnRfcGVyX21zID0gZWRnZVI6OmNwbShHTEkyX2V4cFssMzo4XSkKcm93bmFtZXMoY291bnRfcGVyX21zKSA8LSBHTEkyX2V4cFssMl0KCnJvd3NfZmlsdGVyZWQgPSByb3dTdW1zKGNvdW50X3Blcl9tcyA+MSkgPj0gNgpHTEkyX2V4cF9maWx0ZXJlZCA9IEdMSTJfZXhwW3Jvd3NfZmlsdGVyZWQsXQoKZmlsdGVyZWRfR0xJMl9tYXRyaXggPC0gYXMubWF0cml4KEdMSTJfZXhwX2ZpbHRlcmVkWywzOjhdKQpyb3duYW1lcyhmaWx0ZXJlZF9HTEkyX21hdHJpeCkgPC0gR0xJMl9leHBfZmlsdGVyZWQkZ2VuZQpoZWFkKEdMSTJfZXhwX2ZpbHRlcmVkKVsxOjhdCmBgYAojIyMgUGFydCAxMzogR3JvdXBpbmcgQmFzZWQgb24gdGhlIENlbGwgVHlwZXMKVGhlIHNpbWlsYXIgZ3JvdXBpbmcgd2FzIGRvbmUgcHJldmlvdXNseS4gSG93ZXZlciB0aGlzIHRpbWUgZGlzcGVyc2lvbiB2YWx1ZXMsCm5vcm1hbGl6YXRpb24gZmFjdG9ycyBhbmQgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gbW9kZWwgZml0dGluZyBpcyBhcHBsaWVkCnRvIHRoZSBzYW1wbGVzIG9mIEdMSTIgdHJlYXRtZW50cy4KYGBge3IgbWVzc2FnZT1GQUxTRX0KZ3JvdXBlZF90cmVhdG1lbnRzIDwtIGRhdGEuZnJhbWUobGFwcGx5KGNvbG5hbWVzKEdMSTJfZXhwX2ZpbHRlcmVkKVszOjhdLAogICAgICAgICAgICAgICAgRlVOPWZ1bmN0aW9uKHgpe3VubGlzdChzdHJzcGxpdCh4LCBzcGxpdCA9ICJbMC05XSIpKVtjKDEpXX0pKQpjb2xuYW1lcyhncm91cGVkX3RyZWF0bWVudHMpIDwtIGNvbG5hbWVzKEdMSTJfZXhwKVszOjhdCnJvd25hbWVzKGdyb3VwZWRfdHJlYXRtZW50cykgPC0gYygiY2VsbF90eXBlIikKZ3JvdXBlZF90cmVhdG1lbnRzX25vcm1hbGl6ZWQgPC0gZGF0YS5mcmFtZSh0KGdyb3VwZWRfdHJlYXRtZW50cykpCmQgPSBlZGdlUjo6REdFTGlzdChjb3VudHM9ZmlsdGVyZWRfR0xJMl9tYXRyaXgsIGdyb3VwID0gZ3JvdXBlZF90cmVhdG1lbnRzX25vcm1hbGl6ZWQkY2VsbF90eXBlKQoKbW9kZWxfZGVzaWduX2NlbGx0eXBlcyA8LSBtb2RlbC5tYXRyaXgofmdyb3VwZWRfdHJlYXRtZW50c19ub3JtYWxpemVkJGNlbGxfdHlwZSswKQpkIDwtIGVkZ2VSOjplc3RpbWF0ZURpc3AoZCwgbW9kZWxfZGVzaWduX2NlbGx0eXBlcykKZCA8LSBlZGdlUjo6Y2FsY05vcm1GYWN0b3JzKGQpCmZpdCA8LSBlZGdlUjo6Z2xtUUxGaXQoZCwgbW9kZWxfZGVzaWduX2NlbGx0eXBlcykKcWxmX3Rlc3QuR0xJMnZzRVYgPC0gZWRnZVI6OmdsbVFMRlRlc3QoZml0LCBjb2VmID0gImdyb3VwZWRfdHJlYXRtZW50c19ub3JtYWxpemVkJGNlbGxfdHlwZVlSRyIpCmBgYAojIyMgUGFydCAxNDogU2lnbmlmaWNhbnQgUmVzdWx0cyB3aXRoaW4gdGhlIEZpdHRlZCBNb2RlbApXaXRoIG1vcmUgc3RyaW5nZW50IHAtdmFsdWUgSSB3YXMgYWJsZSB0byBhc3Nlc3MgdGhlIGNyaXRpY2FsIHRocmVzaG9sZCBmb3IgCnRoZSBleHByZXNzaW9uIHRocmVzaG9sZC4gSSBzZXQgdGhlIHAtdmFsdWUgYXMgMC4wMDA1LiBJIGRlY2lkZWQgdG8gcHV0IGl0IGJ5CmFkanVzdGluZyBhbmQgb2JzZXJ2aW5nIGFueSBkaWZmZXJlbmNlLiBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHAtdmFsdWUgMC4wMDUgYW5kIApwLXZhbHVlIDAuMDAwNSBpcyBvbmUuIFRoaXMgbWVhbnMgdGhpcyBwLXZhbHVlIGlzIHNhZmUgdG8gYXNzdW1lIGFzIGEgdGhyZXNob2xkCmZvciBzaWduaWZpY2FuY2UgYW1vbmcgdGhlc2UgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2luZyBnZW5lcy4KYGBge3IgbWVzc2FnZT1GQUxTRX0KcWxmX3RvcF9oaXRzIDwtIGVkZ2VSOjp0b3BUYWdzKHFsZl90ZXN0LkdMSTJ2c0VWLHNvcnQuYnkgPSAiUFZhbHVlIiwgbiA9IG5yb3coZmlsdGVyZWRfR0xJMl9tYXRyaXgpKQoKaGVhZChxbGZfdG9wX2hpdHMpCgpsZW5ndGgod2hpY2gocWxmX3RvcF9oaXRzJHRhYmxlJFBWYWx1ZSA8IDAuMDAwNSkpCiAgICAgICAgICAgCmxlbmd0aCh3aGljaChxbGZfdG9wX2hpdHMkdGFibGUkRkRSIDwgMC4wMDA1KSkKbGVuZ3RoKHdoaWNoKHFsZl90b3BfaGl0cyR0YWJsZSRsb2dGQyA8IDApKQpgYGAKIyMjIFBhcnQgMTU6IFRocmVzaG9sZGVkIEdlbmUgTGlzdCBhbmQgRmluYWwgRU1UIEdlbmUgRGV0ZWN0aW9uClRoZSB0aHJlc2hvbGQgd2FzIGNhbGN1bGF0ZWQgYW5kIGJhc2VkIGl0cyB2YWx1ZSBJIGFzc2Vzc2VkIHRoZSBob3cgbWFueSBnZW5lcyAKYWN0dWFsbHkgc2hvdyB0cmFpdHMgc2ltaWxhciB0byBHTEkyLiBJIHVzZWQgUCB2YWx1ZSAxIHRvIGVsaW1pbmF0ZSBzaWduaWZpY2FudCAKcG9ydGlvbiBvZiB0aGUgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzLiBJIGRpZCBub3QgdXNlIHRoZSBMb2dGQyB0byAKZGlzdGluZ3Vpc2ggYmV0d2VlbiBFTVQgR0xJMiB2cyBub24tRU1UIEdMSTIsIGJlY2F1c2UgYWxsIG9mIGxvZ0ZDIHZhbHVlcyBhcmUKbmVnYXRpdmUuIFRoaXMgaW5kaWNhdGVzIHRoZXJlIGlzIGFsd2F5cyB1cCByZWd1bGF0aW9uIGFmdGVyIHRoZSBEb3ggdHJlYXRtZW50CmFuZCBHTEkyIGV4cHJlc3Npb24gaXMgYWx3YXlzIGhpZ2hlciB0aGFuIHRoZSBjb250cm9sLiBQcmV0dHkgaGlnaCBjb25maWRlbmNlLgpgYGB7ciBtZXNzYWdlPUZBTFNFfQpxbGZfdG9waGl0c193aXRoZ24gPC0gbWVyZ2UoR0xJMl9leHBbLDE6MV0sIHFsZl90b3BfaGl0cywgYnkueT0wLGJ5Lng9MSxhbGwueT1UUlVFKQoKY29sbmFtZXMocWxmX3RvcGhpdHNfd2l0aGduKSA8LSBjKCJHZW5lX3N5bWJvbCIsICJsb2dGQyIsICJsb2dDUE0iLCJGIiwgIlBWYWx1ZSIsICJGRFIiKQoKcWxmX3RvcGhpdHNfd2l0aGduWywibG9nYXJpdGhtaWMiXSA8LSAoLWxvZyhxbGZfdG9waGl0c193aXRoZ24kUFZhbHVlKSkKcWxmX3RvcGhpdHNfd2l0aGduIDwtIHFsZl90b3BoaXRzX3dpdGhnbltvcmRlcihxbGZfdG9waGl0c193aXRoZ24kR2VuZV9zeW1ib2wpLF0KCkdMSTJfZW10X0dlbmVzIDwtIHFsZl90b3BoaXRzX3dpdGhnbiRHZW5lX3N5bWJvbFt3aGljaChxbGZfdG9waGl0c193aXRoZ24kUFZhbHVlIDwgMC4wMDA1CiAgICAgICAgICAgICAgICAmIHFsZl90b3BoaXRzX3dpdGhnbiRsb2dGQyA8IDApXQpHTEkyX25vbl9lbXRnZW5lcyA8LSBxbGZfdG9waGl0c193aXRoZ24kR2VuZV9zeW1ib2xbd2hpY2gocWxmX3RvcGhpdHNfd2l0aGduJFBWYWx1ZSA9PSAxKV0KCndyaXRlLnRhYmxlKHg9R0xJMl9lbXRfR2VuZXMsIGZpbGUgPSBmaWxlLnBhdGgoZ2V0d2QoKSwiZGF0YSIsIkdMSTJfZW10X0dlbmVzLnR4dCIpLAogICAgICAgICAgICAgc2VwID0gIi8iLCByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gRkFMU0UsIHF1b3RlID0gRkFMU0UpCndyaXRlLnRhYmxlKHg9R0xJMl9ub25fZW10Z2VuZXMsIGZpbGUgPSBmaWxlLnBhdGgoZ2V0d2QoKSwiZGF0YSIsIkdMSTJfbm9uX2VtdGdlbmVzLnR4dCIpLAogICAgICAgICAgICAgICAgICAgc2VwID0gIi8iLCByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gRkFMU0UsIHF1b3RlID0gRkFMU0UpCmBgYAojIyMgUGFydCAxNjogR1Byb2ZpbGVyIGZvciBVcHJlZ3VsYXRpb24gYW5kIERvd25yZWd1bGF0aW9uIHBhdGh3YXkgYW5hbHlzaXMKVGhlIEdQcm9maWxlciBhbmFseXNpcyBpbmNsdWRlcyBCSCBjb3JyZWN0aW9uIG1ldGhvZHMgKEZEUikuIEkgc3RpY2tlZCB1c2luZyB0aGUgc2FtZSBtZXRob2QgYmVjYXVzZSBJIHVzZWQgdGhlIHNhbWUgdHlwZSBvZiBtZXRob2Qgb24gbXkgcHJldmlvdXMgYW5hbHlzaXMgb24gRkRSIHBvcnRpb24uIEZvciBib3RoIHVwcmVndWFsdGVkIGFuZCB0aGUgZG93bnJlZ3VsYXRlZCBnZW5lcyBJIGhhdmUgdXNlZCBHTzpCUCAoMjAyMi0xMi0wNCksIFJlYWN0b21lLCBhbmQgV2lraVBhdGh3YXlzKCBmb3IgYW5ub3RhdGlvbi4gVGhlc2UgYW5ub3RhdGlvbnMgYWxsb3dzIGZvciBiZXR0ZXIgYXNlc3NtZW50IG9mIG15IFVwcmVndWFsdGVkIGdlbmVzIGluIHRlcm1zIG9mIGRlZmluaW5nIHRoZSBiaW9sb2dpYyBwYXRod2F5cyB0aGV5IGFyZSBpbnZvdmxlZCBpbi4KCmBgYHtyIG1lc3NhZ2U9RkFMU0V9ClVwcmVndWxhdGVkX2dlbmVzIDwtIHJlYWQudGFibGUoZmlsZT1maWxlLnBhdGgoZ2V0d2QoKSwiZGF0YSIgLCJHTEkyX2VtdF9HZW5lcy50eHQiKSxoZWFkZXIgPSBUUlVFLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UsIGNoZWNrLm5hbWVzID0gRkFMU0UpClVwcmVndWxhdGVkX2dlbmVzIDwtIFVwcmVndWxhdGVkX2dlbmVzWzQ6bnJvdyhVcHJlZ3VsYXRlZF9nZW5lcyksXQpVcHJlZ3VsYXRlZF9HcHJvZmlsZXJfdmFsaWRhdGVkIDwtIGdwcm9maWxlcjI6Omdvc3QocXVlcnkgPSBVcHJlZ3VsYXRlZF9nZW5lcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmdhbmlzbSA9ICJoc2FwaWVucyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjbHVkZV9pZWEgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlcyA9IGMoIkdPOkJQIiwgIlJFQUMiLCAiV1AiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlY3Rpb25fbWV0aG9kID0gImZkciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkX3F1ZXIgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKYGBgCiMjIyBDb250aW51aW5nIEFuYWx5c2lzCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CkRvd25yZWd1bGF0ZWRfZ2VuZXMgPC0gcmVhZC50YWJsZShmaWxlPWZpbGUucGF0aChnZXR3ZCgpLCJkYXRhIiAsIkdMSTJfbm9uX2VtdGdlbmVzLnR4dCIpLGhlYWRlciA9IFRSVUUsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSwgY2hlY2submFtZXMgPSBGQUxTRSkKRG93bnJlZ3VsYXRlZF9nZW5lcyA8LSBEb3ducmVndWxhdGVkX2dlbmVzWzEzOm5yb3coRG93bnJlZ3VsYXRlZF9nZW5lcyksXQpEb3ducmVndWxhdGVkX0dwcm9maWxlcl92YWxpZGF0ZWQgPC0gZ3Byb2ZpbGVyMjo6Z29zdChxdWVyeSA9IERvd25yZWd1bGF0ZWRfZ2VuZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmdhbmlzbSA9ICJoc2FwaWVucyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjbHVkZV9pZWEgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVjdGlvbl9tZXRob2QgPSAiZmRyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWRfcXVlciA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlID0gYygiR086QlAiLCAiUkVBQyIsICJXUCIpKQpgYGAKIyMjIFBhcnQgMTc6IFN1YnNldHRpbmcgdGhlIEdwcm9maWxlciBkb3ducmVndWxhdGVkIGFuZCB1cHJlZ3VhbHRlZCBnZW5lcwpBZnRlciBzdWJzZXR0aW5nIEkgZG8gaGF2ZSA3NzEgZ2VuZXMgdGhhdCBhcmUgZG93biByZWd1bGF0ZWQuIERvd24gcmVndWFsdGVkIGdlbmVzIGFyZSBpbnZvdmxlZCBpbiBjb21tb24gYmlvbG9naWNhbCBwYXRod2F5cyB0aGF0IGFyZSBub3QgaW52b2x2ZWQgaW4gY2FuY2Vyb3VzIGFjdGl2aXRpZXMuCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CkRvd25yZWd1bGF0ZWRfZ2VuZXNfZmlsdGVyZWQgPC0gZGF0YS5mcmFtZSgKICB0ZXJtX25hbWUgPSBEb3ducmVndWxhdGVkX0dwcm9maWxlcl92YWxpZGF0ZWQkcmVzdWx0JHRlcm1fbmFtZVtEb3ducmVndWxhdGVkX0dwcm9maWxlcl92YWxpZGF0ZWQkcmVzdWx0JHRlcm1fc2l6ZSA8IDIwMCAmICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERvd25yZWd1bGF0ZWRfR3Byb2ZpbGVyX3ZhbGlkYXRlZCRyZXN1bHQkdGVybV9zaXplID4gMV0sCiAgIHRlcm1faWQgID0gRG93bnJlZ3VsYXRlZF9HcHJvZmlsZXJfdmFsaWRhdGVkJHJlc3VsdCR0ZXJtX2lkW0Rvd25yZWd1bGF0ZWRfR3Byb2ZpbGVyX3ZhbGlkYXRlZCRyZXN1bHQkdGVybV9zaXplIDwgMjAwICYgCiAgICAgICAgICAgICAgRG93bnJlZ3VsYXRlZF9HcHJvZmlsZXJfdmFsaWRhdGVkJHJlc3VsdCR0ZXJtX3NpemUgPiAxXSwKICBzb3VyY2UgID0gRG93bnJlZ3VsYXRlZF9HcHJvZmlsZXJfdmFsaWRhdGVkJHJlc3VsdCRzb3VyY2VbRG93bnJlZ3VsYXRlZF9HcHJvZmlsZXJfdmFsaWRhdGVkJHJlc3VsdCR0ZXJtX3NpemUgPCAyMDAgJgogICAgICAgICAgICAgIERvd25yZWd1bGF0ZWRfR3Byb2ZpbGVyX3ZhbGlkYXRlZCRyZXN1bHQkdGVybV9zaXplID4gMV0KKQpsZW5ndGgoRG93bnJlZ3VsYXRlZF9nZW5lc19maWx0ZXJlZCR0ZXJtX25hbWUpCmtuaXRyOjprYWJsZShoZWFkKERvd25yZWd1bGF0ZWRfZ2VuZXNfZmlsdGVyZWQsIDEwKSwgZm9ybWF0ID0gImh0bWwiKQpgYGAKIyMjIEZvciBVcHJlZ3VsYXRpb24KQWZ0ZXIgc3Vic2V0dGluZyBJIGRvIGhhdmUgMTEyOCBnZW5lcyB0aGF0IGFyZSBkb3duIHJlZ3VsYXRlZC4gVXAgcmVndWFsdGVkIGdlbmVzIGFyZSBtb3N0bHkgaW52b3ZsZWQgaW4gY2FuY2VyIGFjdGl2aXR5LiBNb3N0IG9mIHRoZSBwYXRod3lhcyBhcmUgcXVpdGUgaW52b3ZsZWQgaW4gY2FuY2Vyb3VzIGFjdGl2dHkuIFRoZXJlIGlzIGEgbG90IGFwb3B0b3NpcyBhbmQgcHJvZ3JhbW1lZCBjZWxsIGRlYXRoIGFjdGl2aXRpZXMuCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIGVycm9yPUZBTFNFfQpVcHJlZ3VsYXRlZF9nZW5lc19maWx0ZXJlZCA8LSBkYXRhLmZyYW1lKAogIHRlcm1fbmFtZSA9IFVwcmVndWxhdGVkX0dwcm9maWxlcl92YWxpZGF0ZWQkcmVzdWx0JHRlcm1fbmFtZVtVcHJlZ3VsYXRlZF9HcHJvZmlsZXJfdmFsaWRhdGVkJHJlc3VsdCR0ZXJtX3NpemUgPCAyMDAgJiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVcHJlZ3VsYXRlZF9HcHJvZmlsZXJfdmFsaWRhdGVkJHJlc3VsdCR0ZXJtX3NpemUgPiAxXSwKICAgdGVybV9pZCAgPSBVcHJlZ3VsYXRlZF9HcHJvZmlsZXJfdmFsaWRhdGVkJHJlc3VsdCR0ZXJtX2lkW1VwcmVndWxhdGVkX0dwcm9maWxlcl92YWxpZGF0ZWQkcmVzdWx0JHRlcm1fc2l6ZSA8IDIwMCAmIAogICAgICAgICAgICAgIFVwcmVndWxhdGVkX0dwcm9maWxlcl92YWxpZGF0ZWQkcmVzdWx0JHRlcm1fc2l6ZSA+IDFdLAogIHNvdXJjZSAgPSBVcHJlZ3VsYXRlZF9HcHJvZmlsZXJfdmFsaWRhdGVkJHJlc3VsdCRzb3VyY2VbVXByZWd1bGF0ZWRfR3Byb2ZpbGVyX3ZhbGlkYXRlZCRyZXN1bHQkdGVybV9zaXplIDwgMjAwICYKICAgICAgICAgICAgICBVcHJlZ3VsYXRlZF9HcHJvZmlsZXJfdmFsaWRhdGVkJHJlc3VsdCR0ZXJtX3NpemUgPiAxXQopCgpsZW5ndGgoVXByZWd1bGF0ZWRfZ2VuZXNfZmlsdGVyZWQkdGVybV9uYW1lKQprbml0cjo6a2FibGUoaGVhZChVcHJlZ3VsYXRlZF9HcHJvZmlsZXJfdmFsaWRhdGVkLCAxMCksIGZvcm1hdCA9ICJodG1sIikKCgpgYGAKCgojIyMgUGFydCAxODogVmlzdWFsaXphdGlvbnMgb2YgdGhlIHVwcmVndWFsdGVkIGFuZCB0aGUgZG93bnJlZ3VsYXRlZCBnZW5lcwpgYGB7ciB9Cmdwcm9maWxlcjI6Omdvc3RwbG90KFVwcmVndWxhdGVkX0dwcm9maWxlcl92YWxpZGF0ZWQpICU+JSBwbG90bHk6OmxheW91dCh0aXRsZSA9ICJVcHJlZ3VsYXRlZCBnZW5lcyAiLCBmb250ID0gbGlzdChzaXplID0gMTApKQoKYGBgCgojIyMgQ29udGludWluZwpgYGB7ciB9Cmdwcm9maWxlcjI6Omdvc3RwbG90KERvd25yZWd1bGF0ZWRfR3Byb2ZpbGVyX3ZhbGlkYXRlZCkgJT4lIHBsb3RseTo6bGF5b3V0KHRpdGxlID0gIkRvd25yZWd1bGF0ZWQgZ2VuZXMgIiwgZm9udCA9IGxpc3Qoc2l6ZSA9IDEwKSkKYGBgCgojIyMgUGFydCAxOTogR1Byb2ZpbGVyIEFuYWx5c2VzIGZvciB0aGUgbWVyZ2VkIGRhdGFzZXQKYGBge3IgbWVzc2FnZT1GQUxTRX0KQ29tcGxldGVfR3Byb2ZpbGVyX0FuYWx5c2VzIDwtIGdwcm9maWxlcjI6Omdvc3QocXVlcnkgPSBtZXJnZWRfaGl0cyRHZW5lX3N5bWJvbCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmdhbmlzbSA9ICJoc2FwaWVucyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjbHVkZV9pZWEgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVjdGlvbl9tZXRob2QgPSAiZmRyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZXMgPSBjKCJHTzpCUCIsICJSRUFDIiwgIldQIikpCgpDb21wbGV0ZV9HcHJvZmlsZXJfQW5hbHlzZXNfZmlsdGVyZWQgPC0gZGF0YS5mcmFtZSh0ZXJtX25hbWUgPSBDb21wbGV0ZV9HcHJvZmlsZXJfQW5hbHlzZXMkcmVzdWx0JHRlcm1fbmFtZVtDb21wbGV0ZV9HcHJvZmlsZXJfQW5hbHlzZXMkcmVzdWx0JHRlcm1fc2l6ZSA8IDIwMCAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29tcGxldGVfR3Byb2ZpbGVyX0FuYWx5c2VzJHJlc3VsdCR0ZXJtX3NpemUgPiAxXSwKICB0ZXJtX2lkID0gQ29tcGxldGVfR3Byb2ZpbGVyX0FuYWx5c2VzJHJlc3VsdCR0ZXJtX2lkW0NvbXBsZXRlX0dwcm9maWxlcl9BbmFseXNlcyRyZXN1bHQkdGVybV9zaXplIDwgMjAwICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbXBsZXRlX0dwcm9maWxlcl9BbmFseXNlcyRyZXN1bHQkdGVybV9zaXplID4gMV0sCiAgc291cmNlID0gQ29tcGxldGVfR3Byb2ZpbGVyX0FuYWx5c2VzJHJlc3VsdCRzb3VyY2VbQ29tcGxldGVfR3Byb2ZpbGVyX0FuYWx5c2VzJHJlc3VsdCR0ZXJtX3NpemUgPCAyMDAgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbXBsZXRlX0dwcm9maWxlcl9BbmFseXNlcyRyZXN1bHQkdGVybV9zaXplID4gMV0pCgpsZW5ndGgoQ29tcGxldGVfR3Byb2ZpbGVyX0FuYWx5c2VzX2ZpbHRlcmVkJHRlcm1fbmFtZSkKa25pdHI6OmthYmxlKGhlYWQoQ29tcGxldGVfR3Byb2ZpbGVyX0FuYWx5c2VzLCAxKSwgZm9ybWF0ID0gImh0bWwiKQpgYGAKIyMjIENvbnRpbnVpbmcKYGBge3IgbWVzc2FnZT1GQUxTRX0KZ3Byb2ZpbGVyMjo6Z29zdHBsb3QoQ29tcGxldGVfR3Byb2ZpbGVyX0FuYWx5c2VzKSAlPiUgcGxvdGx5OjpsYXlvdXQodGl0bGUgPSAiQ29tcGxldGUgcGxvdCBwbG90IiwgZm9udCA9IGxpc3Qoc2l6ZSA9IDEwKSkKYGBgCgojIyMgUGFydCAyMDpJbnRlcnByZXRhdGlvbgoKIyMjIyBEbyB0aGUgb3Zlci1yZXByZXNlbnRhdGlvbiByZXN1bHRzIHN1cHBvcnQgY29uY2x1c2lvbnMgb3IgbWVjaGFuaXNtIGRpc2N1c3NlZCBpbiB0aGUgb3JpZ2luYWwgcGFwZXIgPyA8YnI+CgpZZXMgdGhlIG92ZXItcmVwcmVzZW50YXRpb24gcmVzdWx0cyB3ZSBmaW5kIGlzIGNvcnJlbGF0ZWQgdG8gdGhlIGNvbmNsdXNpb24gdGhlCmF1dGhvcnMgbWFrZS4gVGhleSBjb25jbHVkZSB0aGF0IGdlbmVzIGhhdmluZyBoaWdoZXIgR0xJMiBleHByZXNzaW9uLCBtb3JlIApkaWZmZXJlbnRpYWxseSBleHByZXNzZWQsIGFyZSBtb3JlIHBvc3NpYmxlIHRvIGJlIEVNVCBnZW5lcy4gQWRkaXRpb25hbGx5LCB3ZSAKZm91bmQgdGhlcmUgaXMgYWx3YXlzIGhpZ2hlciBleHByZXNzaW9uIG9uIEdMSTIgdHJlYXRtZW50cyBnaXZlbiB0aGlzIGlzIGEgc3Ryb25nCm9uY29nZW5lIGFjdGluZyBpbiBiYXNhbC1zdWItdHlwZSBzd2l0Y2hpbmcgdHJpZ2dlcmluZyBFTVQgc3dpdGNoaW5nLiBBcyBpdCBpcyBvYnZpb3VzIGZyb20gdGhlIHZpc3VhbGl6YXRpb24gdGhlIHVwcmVndWFsdGVkIGdlbmVzIGFyZSBtb3JlIGNsdXN0ZXJlZCBhbmQgYXJlIG11Y2ggbW9yZSBpbiB0aGUgZG93bnJlZ3VhbHRlZCBnZW5lcyBUaGlzIHN1cHBvcnRzIHRoZSBoeXBvdGhlc2lzIG9mIGF1dGhvcnMsIGNvbmNsdWRpbmcgdGhlIEVNVCBnZW5lcyB0byBiZSBoaWdoZXIgZXhwcmVzc2lvbiB0aGFuIHRoYXQgb2YgdGhlIGRvd25yZWd1YWx0ZWQgZ2VuZXMuCgojIyMjIENhbiB5b3UgZmluZCBldmlkZW5jZSwgaS5lLiBwdWJsaWNhdGlvbnMsIHRvIHN1cHBvcnQgc29tZSBvZiB0aGUgcmVzdWx0cyB0aGF0IHlvdSBzZWUuIEhvdyBkb2VzIHRoaXMgZXZpZGVuY2Ugc3VwcG9ydCB5b3VyIHJlc3VsdHMgPyA8YnI+CgpUaGUgcGFwZXIgKFBhc2NhIGRpIE1hZ2xpYW5vIGV0IGFsLiwyMDA2KSBoYXMgYWxyZWFkeSBpbmRpY2F0ZWQgaW5jcmVhc2UgCmV4cHJlc3Npb24gb2YgR0xJMiBjYW4gbGVhZCB0byBTSEggZ2VuZSByZWR1Y3Rpb24uIFRoaXMgZ2VuZSBoYXMgYmVlbiBrbm93biB0byAKYmUgYW4gb25jb2dlbmUgYXNzb2NpYXRlZCB3aXRoIGJhc2FsLXN1Yi10eXBlIHN3aXRjaGluZyBpbiBQREFDLiBUaGV5IGFjdGl2YXRlIApHTEkyIGNvbnN0YW50bHkgd2hpY2ggaGFzIHRoZSBzYW1lIGV4cGVjdGVkIG91dGNvbWUgaW4gb3VyIGRhdGEgc2V0IGhhdmluZwpHTEkyIGV4cHJlc3NpbmcgdmVjdG9ycyB3aXRoIGNvbnN0YW50IERveCB0cmVhdG1lbnQuIEluIGNvbmNsdXNpb24gdGhlc2UgdHdvCnBhcGVyIGZpbmRpbmdzIGNvcnJlbGF0ZSBlYWNoIG90aGVyLiBUaGV5IHNob3cgdGhhdCB0aGUgRU1UIGdlbmVzIHRvIGJlIGFidW5kYW50IGluIHRoZWlyIGJpb2xvZ2ljYWwgZnVuY3Rpb25zIGFuZCB0aGVpciBwYXRod2F5IGludm92bGVtZW50LgoKIyMgUmVmZXJlbmNlcwo=